package org.agony2d.view.puppet 
{
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import org.agony2d.core.agony_internal;
	import org.agony2d.debug.Logger;
	import org.agony2d.view.core.Component;
	import org.agony2d.view.core.ComponentProxy;
	
	use namespace agony_internal;
	
	/** 九宫格傀儡
	 *  [◆◆◇]
	 * 		1. addNineScaleData
	 * 		2. removeNineScaleData
	 * 		3. clearAllData
	 *  [◆]
	 * 		1. width
	 * 		2. height
	 * 		3. nineScaleData
	 *  [◆◆]
	 * 		1. setSize
	 *  [◎]
	 * 		a. 仅使用width，height，setSize调整尺寸，不要使用scaleX，scaleY，rotation!!
	 */
public class NineScalePuppet extends ComponentProxy
{
	
	public function NineScalePuppet( nineScaleData:String, width:Number = -1, height:Number = -1 ) 
	{
		m_view               =  NineScalePuppetComp.getNineScaleComp(this)
		m_view.m_currWidth   =  width
		m_view.m_currHeight  =  height
		this.nineScaleData   =  nineScaleData
	}
	
	/** ◆◆◇加入九宫格数据
	 *  @param	source
	 *  @param	dataName
	 *  @param	scaleAreaSize
	 */
	public static function addNineScaleData( source:BitmapData, dataName:String, scaleAreaSize:int = 3 ) : void
	{
		var prop:NineScaleProp
		var BA:BitmapData
		var rect:Rectangle
		var point:Point
		var left:int, right:int, top:int, bottom:int, length:int
		
		if (m_nineScaleProps[dataName])
		{
			return
		}
		if (source.width < scaleAreaSize + 4 || source.height < scaleAreaSize + 4)
		{
			Logger.reportError('NineScalePuppet', 'addNineScaleData', '源画像尺寸错误.')
		}
		prop                        =  new NineScaleProp()
		prop.name                   =  dataName
		m_nineScaleProps[dataName]  =  prop
		rect                        =  new Rectangle()
		point                       =  new Point()
		
		// Padding
		left    =  prop.left    =  int(source.width  / 2) - 1
		right   =  prop.right   =  source.width - left - scaleAreaSize
		top     =  prop.top     =  int(source.height / 2) - 1;
		bottom  =  prop.bottom  =  source.height - top - scaleAreaSize
		length  =  prop.length  =  scaleAreaSize
		
		// Top
		BA            =  new BitmapData( left, top, true, 0x0 )
		prop.sevenBA  =  BA
		rect.width    =  left
		rect.height   =  top
		BA.copyPixels(source, rect, point);
		BA            =  new BitmapData( 3, top, true, 0x0 )
		prop.eightBA  =  BA
		rect.x        =  left
		rect.width    =  scaleAreaSize
		BA.copyPixels(source, rect, point);
		BA           =  new BitmapData( right, top, true, 0x0 )
		prop.nineBA  =  BA
		rect.x       =  left + scaleAreaSize
		rect.width   =  right
		BA.copyPixels(source, rect, point)
		
		// Middle
		BA           =  new BitmapData( left, scaleAreaSize, true, 0x0 )
		prop.fourBA  =  BA
		rect.x       =  0
		rect.width   =  left
		rect.y       =  top
		rect.height  =  scaleAreaSize
		BA.copyPixels(source, rect, point);
		BA           =  new BitmapData( scaleAreaSize, scaleAreaSize, true, 0x0 )
		prop.fiveBA  =  BA
		rect.x       =  left
		rect.width   =  scaleAreaSize
		BA.copyPixels(source, rect, point);
		BA          =  new BitmapData( right, 3, true, 0x0 )
		prop.sixBA  =  BA
		rect.x      =  left + scaleAreaSize
		rect.width  =  right
		BA.copyPixels(source, rect, point);
		
		// Bottom
		BA           =  new BitmapData( left, bottom, true, 0x0 )
		prop.oneBA   =  BA
		rect.x       =  0
		rect.width   =  left
		rect.y       =  top + scaleAreaSize
		rect.height  =  bottom
		BA.copyPixels(source, rect, point)
		BA          =  new BitmapData( scaleAreaSize, bottom, true, 0x0 )
		prop.twoBA  =  BA
		rect.x      =  left
		rect.width  =  scaleAreaSize
		BA.copyPixels(source, rect, point)
		BA            =  new BitmapData( right, bottom, true, 0x0 )
		prop.threeBA  =  BA
		rect.x        =  left + scaleAreaSize
		rect.width    =  right
		BA.copyPixels(source, rect, point)
	}
	
	/** ◆◆◇削除九宫格数据
	 *  @param	dataName
	 */
	public static function removeNineScaleData( dataName:String ) : void
	{
		delete m_nineScaleProps[dataName]
	}
	
	/** ◆◆◇削除全部九宫格数据
	 *  @param	dataName
	 */
	public static function clearAllData( dataName:String ) : void
	{
		m_nineScaleProps = {}
	}
	
	/** ◆宽度 */
	final override public function get width() : Number{ return m_view.width }
	final public function set width( v:Number ) : void { m_view.width = v }
	
	/** ◆高度 */
	final override public function get height() : Number { return m_view.height }
	final public function set height( v:Number ) : void { m_view.height = v }
	
	/** ◆九宫格数据 */
	final public function get nineScaleData() : String { return m_view.m_dataName }
	final public function set nineScaleData( v:String ) : void
	{
		var prop:NineScaleProp
		
		prop = m_nineScaleProps[v]
		if (!prop)
		{
			Logger.reportError(this, 'set data', '未知的九宫格画像数据.')
		}
		m_view.setNineScaleProp(prop)
	}
	
	/** ◆◆设置尺寸
	 *  @param	width
	 *  @param	height
	 */
	final public function setSize( width:Number, height:Number ) : void
	{
		m_view.setSize(width, height)
	}
	
	final override agony_internal function get view() : Component { return m_view }
	
	final override agony_internal function get shell() : DisplayObject { return m_view }
	
	agony_internal static var m_nineScaleProps:Object = {}
	
	agony_internal var m_view:NineScalePuppetComp
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import org.agony2d.core.agony_internal;
import org.agony2d.view.core.ComponentProxy;
import org.agony2d.view.puppet.supportClasses.PuppetComp;

use namespace agony_internal;

final class NineScalePuppetComp extends PuppetComp
{
	
	public function NineScalePuppetComp()
	{
		m_oneBP    =  new Bitmap()
		m_twoBP    =  new Bitmap()
		m_threeBP  =  new Bitmap()
		m_fourBP   =  new Bitmap()
		m_fiveBP   =  new Bitmap()
		m_sixBP    =  new Bitmap()
		m_sevenBP  =  new Bitmap()
		m_eightBP  =  new Bitmap()
		m_nineBP   =  new Bitmap()
		
		this.addChild(m_oneBP)
		this.addChild(m_twoBP)
		this.addChild(m_threeBP)
		this.addChild(m_fourBP)
		this.addChild(m_fiveBP)
		this.addChild(m_sixBP)
		this.addChild(m_sevenBP)
		this.addChild(m_eightBP)
		this.addChild(m_nineBP)
	}
	
	final agony_internal function get minWidth() : Number { return left + right }
	final agony_internal function get minHeight() : Number { return top + bottom }
	
	final override public function get width() : Number { return m_currWidth }
	final override public function set width( v:Number ) : void
	{
		m_currWidth = v
		this.rejustImagePostion();
	}
	
	final override public function get height() : Number { return m_currHeight }
	final override public function set height( v:Number ) : void
	{
		m_currHeight = v
		this.rejustImagePostion();
	}
	
	final agony_internal function setSize( width:Number, height:Number ) : void
	{
		m_currWidth   =  width
		m_currHeight  =  height
		this.rejustImagePostion();
	}
	
	final agony_internal function setNineScaleProp( prop:NineScaleProp ) : void
	{
		if (m_dataName == prop.name)
		{
			return
		}
		m_dataName   =  prop.name
		this.left    =  prop.left
		this.right   =  prop.right
		this.top     =  prop.top
		this.bottom  =  prop.bottom
		this.length  =  prop.length
		m_oneBP.bitmapData    =  prop.oneBA
		m_twoBP.bitmapData    =  prop.twoBA
		m_threeBP.bitmapData  =  prop.threeBA
		m_fourBP.bitmapData   =  prop.fourBA
		m_fiveBP.bitmapData   =  prop.fiveBA
		m_sixBP.bitmapData    =  prop.sixBA
		m_sevenBP.bitmapData  =  prop.sevenBA
		m_eightBP.bitmapData  =  prop.eightBA
		m_nineBP.bitmapData   =  prop.nineBA
		m_eightBP.x = m_fiveBP.x = m_twoBP.x = left
		m_fourBP.y  = m_fiveBP.y = m_sixBP.y = top
		this.rejustImagePostion();
	}
	
	final agony_internal function rejustImagePostion() : void
	{
		if (m_currWidth < this.minWidth)
		{
			m_currWidth = this.minWidth
		}
		if(m_currHeight < this.minHeight)
		{
			m_currHeight = this.minHeight
		}
		// 852
		m_eightBP.width = m_fiveBP.width  = m_twoBP.width  = m_currWidth - left - right
		// 963
		m_nineBP.x      = m_sixBP.x       = m_threeBP.x    = m_currWidth - right
		// 456
		m_fourBP.height = m_fiveBP.height = m_sixBP.height = m_currHeight - top - bottom
		// 123
		m_oneBP.y       = m_twoBP.y       = m_threeBP.y    = m_currHeight - bottom
	}

	final agony_internal override function dispose() : void
	{
		m_oneBP.bitmapData = m_twoBP.bitmapData = m_threeBP.bitmapData = m_fourBP.bitmapData = m_fiveBP.bitmapData = m_sixBP.bitmapData = m_sevenBP.bitmapData = m_eightBP.bitmapData = m_nineBP.bitmapData = null
		m_dataName = null
		super.dispose()
	}
	
	final override agony_internal function recycle() : void
	{
		cachedNSList[cachedNSLength++] = this
	}
	
	agony_internal static function getNineScaleComp( proxy:ComponentProxy ) : NineScalePuppetComp
	{
		var NS:NineScalePuppetComp
		
		NS = (cachedNSLength > 0 ? cachedNSLength-- : 0) ? cachedNSList.pop() : new NineScalePuppetComp()
		NS.m_proxy = proxy
		NS.m_notifier.setTarget(proxy)
		return NS
	}
	
	agony_internal static var cachedNSList:Array = []
	agony_internal static var cachedNSLength:int;
	
	agony_internal var m_sevenBP:Bitmap, m_eightBP:Bitmap, m_nineBP:Bitmap, m_fourBP:Bitmap, m_fiveBP:Bitmap, m_sixBP:Bitmap, m_oneBP:Bitmap, m_twoBP:Bitmap, m_threeBP:Bitmap
	agony_internal var left:int, right:int, top:int, bottom:int, length:int
	agony_internal var m_currWidth:Number, m_currHeight:Number
	agony_internal var m_dataName:String
}
final class NineScaleProp
{
	internal var sevenBA:BitmapData, eightBA:BitmapData, nineBA:BitmapData, fourBA:BitmapData, fiveBA:BitmapData, sixBA:BitmapData, oneBA:BitmapData, twoBA:BitmapData, threeBA:BitmapData
	internal var left:int, right:int, top:int, bottom:int, length:int
	internal var name:String
}